<html>
<head><meta charset="utf-8"><title>the guarantees of const · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html">the guarantees of const</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="247227473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247227473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247227473">(Jul 26 2021 at 16:35)</a>:</h4>
<p>Is there a document anywhere describing what the "guarantees" of const are? It's difficult for me to determine what properties of const are merely artifacts of the current implementation and which are hard design requirements that are guaranteed to be upheld in the future. For example, <code>const fn</code>s must be deterministic at compile-time, right? Is that something that people will always be able to rely on? Similarly, is it guaranteed that <code>const fn</code>s must never be able to determine if the current execution environment is compile-time or runtime? Ideally the page in the reference would mention such things, although I don't trust what's currently written there, since it says "Calling a const function at compile-time will always yield the same result as calling it at runtime, even when called multiple times.", which I'm not sure will be true in the future given the prior discussion here about stabilizing const fn transmute</p>



<a name="247228141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247228141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247228141">(Jul 26 2021 at 16:40)</a>:</h4>
<blockquote>
<p>Similarly, is it guaranteed that const fns must never be able to determine if the current execution environment is compile-time or runtime? </p>
</blockquote>
<p>I hope that wouldn't be the case. In many cases it can be useful to offer a naive const implementation so that CTFE works but implement an optimized one for runtime.</p>



<a name="247230078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247230078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247230078">(Jul 26 2021 at 16:55)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> there is some of that at <a href="https://github.com/rust-lang/const-eval/">https://github.com/rust-lang/const-eval/</a></p>



<a name="247230250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247230250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247230250">(Jul 26 2021 at 16:57)</a>:</h4>
<blockquote>
<p>Similarly, is it guaranteed that const fns must never be able to determine if the current execution environment is compile-time or runtime? I</p>
</blockquote>
<p>no, I dont think this is something we'll be able to uphold, at least in unsafe code -- and while we can try to declare this a bug, I dont think we should make it UB as there just is no good way to test for this, and un-testable UB is something Rust should not have IMO.</p>



<a name="247233383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247233383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247233383">(Jul 26 2021 at 17:20)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247230250">said</a>:</p>
<blockquote>
<blockquote>
<p>Similarly, is it guaranteed that const fns must never be able to determine if the current execution environment is compile-time or runtime? I</p>
</blockquote>
<p>no, I dont think this is something we'll be able to uphold, at least in unsafe code -- and while we can try to declare this a bug, I dont think we should make it UB as there just is no good way to test for this, and un-testable UB is something Rust should not have IMO.</p>
</blockquote>
<p>I'd also argue that it's a good idea to allow const functions to detect whether they are being evaluated at compile time or runtime. C++ added this, and it allows my cxmath library to not be painfully slow when evaluated at runtime (it evaluates 10+ terms of a taylor series for most functions).</p>



<a name="247234695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247234695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247234695">(Jul 26 2021 at 17:31)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> but the library still is expected to behave the same in both cases, it just provides more efficient implementations tailored to the context it is running in?</p>



<a name="247238962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247238962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247238962">(Jul 26 2021 at 18:02)</a>:</h4>
<p>Thanks for the info, I forget which discussion it was where someone mentioned that being able to detect am-I-in-const was undesirable, but it seemed like it might be pretty hard to guarantee in practice. And the ability to detect am-I-in-const definitely means that the aforementioned line from the reference ("Calling a const function at compile-time will always yield the same result as calling it at runtime, even when called multiple times.") is definitely not going to be true</p>



<a name="247239125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247239125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247239125">(Jul 26 2021 at 18:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247234695">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> but the library still is expected to behave the same in both cases, it just provides more efficient implementations tailored to the context it is running in?</p>
</blockquote>
<p>Yes, though the output may slightly differ due to the different implementation - ideally this is within 0.5 ULPs, though.</p>



<a name="247239625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247239625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247239625">(Jul 26 2021 at 18:06)</a>:</h4>
<p>ah yeah floats makes this even more "fun" -- but other than that, yes indeed this is the kind of thing for which we might also want a way to dispatch to different code between const and runtime in Rust</p>



<a name="247239738"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247239738" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247239738">(Jul 26 2021 at 18:07)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> that line will still be something we expect all public <code>const fn</code> to adhere to -- similar to how we expect all public <code>fn</code> to be UB-free when called from safe code in arbitrary ways</p>



<a name="247244174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247244174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247244174">(Jul 26 2021 at 18:40)</a>:</h4>
<p>What is the severity of the "expect" in that statement? Is it UB for a function to produce different output at compile time than at runtime, or is it merely discouraged, in the same way that it's discouraged for a specialized function to produce a different result?</p>



<a name="247244473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247244473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247244473">(Jul 26 2021 at 18:43)</a>:</h4>
<p>Because if it's UB, then that means that every mechanism by which code detects am-I-in-const has to be <code>unsafe</code></p>



<a name="247244855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247244855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247244855">(Jul 26 2021 at 18:46)</a>:</h4>
<p>That would make using it to overload fp functions impossible, though.</p>



<a name="247244948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247244948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247244948">(Jul 26 2021 at 18:47)</a>:</h4>
<p>And, as I mentioned, the kinds of things you need to do to make fp functions work in <code>const</code> can be (and are) painfully slow when they end up at runtime).</p>



<a name="247246553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247246553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247246553">(Jul 26 2021 at 19:00)</a>:</h4>
<p>So then it merely has to be "discouraged", right? Which has consequences for type safety, yeah?</p>



<a name="247246981"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247246981" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247246981">(Jul 26 2021 at 19:04)</a>:</h4>
<p>Let's keep in mind that any outcome where <code>const fn</code> can cause UB without <code>unsafe</code> being used anywhere is a total non-starter and must be avoided at all costs. And if <em>any</em> <code>const fn</code> can exhibit UB by detecting am-I-in-const without <code>unsafe</code>, then <em>every</em> <code>const fn</code> has to be unsafe to call, always, which is also a non-starter</p>



<a name="247247446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247247446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247247446">(Jul 26 2021 at 19:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247246553">said</a>:</p>
<blockquote>
<p>So then it merely has to be "discouraged", right? Which has consequences for type safety, yeah?</p>
</blockquote>
<p>Yeah. I'd have to assume so. One notable thing, though, that C++ has with it's detection mechanism <code>std::is_constant_evaluated()</code>, is that it doesn't actually detect whether it is evaluated at compile-time, rather it only detects cases it must be (required core-constant-expressions), and a few other cases that special-case core-constant expressions (such as static/tls initializers). The trivial example is that:</p>
<div class="codehilite" data-code-language="C++"><pre><span></span><code><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">is_constant_evaluated</span><span class="p">()</span> <span class="o">?</span> <span class="mi">5</span> <span class="o">:</span> <span class="mi">7</span><span class="p">;</span>
</code></pre></div>
<p>Produces x==7, whereas</p>
<div class="codehilite" data-code-language="C++"><pre><span></span><code><span class="k">constexpr</span> <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">is_constant_evaluated</span><span class="p">()</span> <span class="o">?</span> <span class="mi">5</span> <span class="o">:</span> <span class="mi">7</span><span class="p">;</span>
</code></pre></div>
<p>Produces x==5. <br>
If rust had the same property for it's <code>am-i-in-const</code>, then it would mitigate the issue, assuming the runtime version was still deterministic.</p>



<a name="247248703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247248703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247248703">(Jul 26 2021 at 19:18)</a>:</h4>
<p>I don't know if C++'s <code>is_constant_evaluated</code> makes sense for Rust. I think you'd really want something more like specialization, where it's possible to define both a <code>const fn foo</code> and a <code>fn foo</code>, and if you only define the former than that's what gets used for both compile-time and runtime, and if you define both then the first gets used at compile-time and the second at runtime</p>



<a name="247248998"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247248998" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247248998">(Jul 26 2021 at 19:20)</a>:</h4>
<p>Either way, my main point is that it may be beneficial to inherit the same property. So if the runtime version exists it is always called whenever the const version isn't required. The translation of the example would be:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kt">i32</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="mi">5</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kt">i32</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="mi">7</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">(){</span><span class="w"></span>
<span class="w">     </span><span class="k">const</span><span class="w"> </span><span class="n">X</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">foo</span><span class="p">();</span><span class="w"> </span><span class="c1">// Always 5</span>
<span class="w">     </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">foo</span><span class="p">();</span><span class="w"> </span><span class="c1">// Always 7</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="247249930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247249930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247249930">(Jul 26 2021 at 19:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247244174">said</a>:</p>
<blockquote>
<p>What is the severity of the "expect" in that statement? Is it UB for a function to produce different output at compile time than at runtime, or is it merely discouraged, in the same way that it's discouraged for a specialized function to produce a different result?</p>
</blockquote>
<p>I dont think it should be UB, since I cant think of a way for Miri to detect this -- and I think all UB needs to be testable.</p>



<a name="247250181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250181">(Jul 26 2021 at 19:31)</a>:</h4>
<blockquote>
<p>Yeah. I'd have to assume so. One notable thing, though, that C++ has with it's detection mechanism std::is_constant_evaluated(), is that it doesn't actually detect whether it is evaluated at compile-time, rather it only detects cases it must be (required core-constant-expressions), and a few other cases that special-case core-constant expressions (such as static/tls initializers). The trivial example is that:</p>
</blockquote>
<p>I think what you are saying here is that it tests <em>CTFE</em>, not <em>constant propagation</em>. And I think that is indeed the only sensible thing to do. <code>const</code> in Rust is  about CTFE. This entire discussion is about CTFE. constant propagation is an <em>optimization</em> and thus, by definition, has no observable effects (except for performance, and possibly a reduction in non-determinism).</p>



<a name="247250335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250335">(Jul 26 2021 at 19:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247248703">said</a>:</p>
<blockquote>
<p>I don't know if C++'s <code>is_constant_evaluated</code> makes sense for Rust. I think you'd really want something more like specialization, where it's possible to define both a <code>const fn foo</code> and a <code>fn foo</code>, and if you only define the former than that's what gets used for both compile-time and runtime, and if you define both then the first gets used at compile-time and the second at runtime</p>
</blockquote>
<p>the API <span class="user-mention" data-user-id="124288">@oli</span> was suggesting is something like <code>select_const(const_fn: const impl FnOnce(), runtime_fn: impl FnOnce())</code>. this would also let us only test the "const" 'branch' for const-validity.</p>



<a name="247250474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250474">(Jul 26 2021 at 19:33)</a>:</h4>
<p>so to be clear, there's no imaginable context where type safety would depend on a <code>const fn</code> having the same value at runtime that it does at compile-time, and while it remains true that a <code>const fn</code> called-at-compile-time must be deterministic, that same <code>const fn</code> called-at-runtime is allowed to be nondeterministic?</p>



<a name="247250598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250598">(Jul 26 2021 at 19:34)</a>:</h4>
<blockquote>
<p>Either way, my main point is that it may be beneficial to inherit the same property. So if the runtime version exists it is always called whenever the const version isn't required. The translation of the example would be:</p>
</blockquote>
<p>CTFE and constant propagation are two basically entirely orthogonal pieces that just both happen to have "constant" in their name. Sadly, many people seem confused by this and keep bringing up const-prop in CTFE discussions. But there really is not much of a connection.</p>
<p>So, yes, this <code>select_const</code> would check for "being evaluatied as part of a ´const<code> or </code>static` item, const generic, or array length" -- IOW, CTFE.</p>



<a name="247250658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250658">(Jul 26 2021 at 19:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247250474">said</a>:</p>
<blockquote>
<p>so to be clear, there's no imaginable context where type safety would depend on a <code>const fn</code> having the same value at runtime that it does at compile-time, and while it remains true that a <code>const fn</code> called-at-compile-time must be deterministic, that same <code>const fn</code> called-at-runtime is allowed to be nondeterministic?</p>
</blockquote>
<p>oh there are many imaginable contexts :)</p>



<a name="247250703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250703">(Jul 26 2021 at 19:35)</a>:</h4>
<p>there is this entire idea that a <code>const fn</code> <em>must behave like a pure function at runtime</em>.</p>



<a name="247250729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250729">(Jul 26 2021 at 19:35)</a>:</h4>
<p>this is currently true. and it could be useful for unsafe (runtime) code to exploit.</p>



<a name="247250737"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250737" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250737">(Jul 26 2021 at 19:35)</a>:</h4>
<blockquote>
<p>Sadly, many people seem confused by this and keep bringing up const-prop in CTFE discussions</p>
</blockquote>
<p>In the float context it comes up a lot, largely because they use the same machinery (both use LLVM APFloat, or a port of it). But yes, they're orthogonal aside from sharing some infrastructure in various places.</p>



<a name="247250942"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250942" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250942">(Jul 26 2021 at 19:37)</a>:</h4>
<p>Centril was a big fan of this and kept asking us to maintain this property. They are no longer around though and I don't know anyone else who has grand plans along these lines.</p>



<a name="247250966"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247250966" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247250966">(Jul 26 2021 at 19:37)</a>:</h4>
<p>I personally don't really have a strong opinion either way, I just try to help the lang team notice when they cross this line :)</p>



<a name="247251109"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247251109" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247251109">(Jul 26 2021 at 19:38)</a>:</h4>
<p>and indeed stabilizing <code>const_fn_transmute</code> is, basically, crossing that line... and there hasn't been that much discussion around this. which is surprising to me, and I am a bit worried not everyone realized the gravity of this decision.</p>



<a name="247251310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247251310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247251310">(Jul 26 2021 at 19:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247250598">said</a>:</p>
<blockquote>
<blockquote>
<p>Either way, my main point is that it may be beneficial to inherit the same property. So if the runtime version exists it is always called whenever the const version isn't required. The translation of the example would be:</p>
</blockquote>
<p>CTFE and constant propagation are two basically entirely orthogonal pieces that just both happen to have "constant" in their name. Sadly, many people seem confused by this and keep bringing up const-prop in CTFE discussions. But there really is not much of a connection.</p>
</blockquote>
<p>In C++, there is a intersection of a subset of viable cases of constant-propagation and what rust calls CTFE, which are known as <em>core constant expressions</em>, and these are expressions that the compiler is blessed by the standard to evaluating at compile time. The notable distinction of <code>std::is_constant_evaluated()</code> is that it doesn't test if the expression that evaluates it is a <em>core constant expressions</em> (in fact, were that the case, it would also return true, because the simple call itself is a <em>core constant expression</em>), but it tests whether the expression is <em>manifestly constant evaluated</em>. </p>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247250474">said</a>:</p>
<blockquote>
<p>so to be clear, there's no imaginable context where type safety would depend on a <code>const fn</code> having the same value at runtime that it does at compile-time, and while it remains true that a <code>const fn</code> called-at-compile-time must be deterministic, that same <code>const fn</code> called-at-runtime is allowed to be nondeterministic?</p>
</blockquote>
<p>I can write a trivial example right now:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// foo is a `const fn()-&gt;i32` or some other constant expression</span>
<span class="k">const</span><span class="w"> </span><span class="n">X</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">foo</span><span class="p">();</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">foo</span><span class="p">();</span><span class="w"></span>
<span class="k">if</span><span class="w"> </span><span class="n">X</span><span class="o">!=</span><span class="n">x</span><span class="p">{</span><span class="w"> </span><span class="k">unsafe</span><span class="p">{</span><span class="n">core</span>::<span class="n">hint</span>::<span class="n">unreachable_unchecked</span><span class="p">()}}</span><span class="w"></span>
</code></pre></div>
<p>The question is whether there are any reasonable examples of such a context.</p>



<a name="247251398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247251398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247251398">(Jul 26 2021 at 19:40)</a>:</h4>
<p>Note that currently that code is sound <code>∀const fn foo()-&gt;i32</code>.</p>



<a name="247251600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247251600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247251600">(Jul 26 2021 at 19:42)</a>:</h4>
<blockquote>
<p>and these are expressions that the compiler is blessed by the standard to evaluating at compile time</p>
</blockquote>
<p>why does the standard need to bless this? the as-if rule already blesses this...</p>



<a name="247252094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247252094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247252094">(Jul 26 2021 at 19:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247251600">said</a>:</p>
<blockquote>
<p>why does the standard need to bless this? the as-if rule already blesses this...</p>
</blockquote>
<p>There are a few cases that an expression being a <em>core constant expression</em> alters the observable behaviour. Notably, an object with static/thread storage duration that has an initializer consisting of only <em>core constant expressions</em> was required (merely permitted in C++11), to have constant-initialization, rather than zero-init followed by dynamic init (which is observable for trivially-copyable types by copying the bytes out in an earlier dynamic initializer). This case notably is also <em>manifestly-constant evaluated</em> (being one of the two special cases that don't require a constant expression). It's also easier to const-prop a core constant expression, because it doesn't involve doing things like calling a function defined in another translation unit.</p>



<a name="247252603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247252603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247252603">(Jul 26 2021 at 19:51)</a>:</h4>
<p>okay so that sounds like a lot of messy complications that Rust avoided :)</p>



<a name="247258269"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247258269" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247258269">(Jul 26 2021 at 20:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/the.20guarantees.20of.20const/near/247251109">said</a>:</p>
<blockquote>
<p>and indeed stabilizing <code>const_fn_transmute</code> is, basically, crossing that line... and there hasn't been that much discussion around this. which is surprising to me, and I am a bit worried not everyone realized the gravity of this decision.</p>
</blockquote>
<p>I would be extremely worried were it not that you seem to have signed off on it. :P I figure if Ralf, the expert on the intersection of const and unsafety, thinks it's fine to allow this, then presumably nothing <em>too</em> bad can happen...</p>



<a name="247258723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247258723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247258723">(Jul 26 2021 at 20:40)</a>:</h4>
<p>There are other possible problems than UB, e.g. being mutually exclusive with some desirable future extension. Or specification complexity.</p>



<a name="247260540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247260540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247260540">(Jul 26 2021 at 20:55)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> there's nothing fundamentally wrong with runtime-impure <code>const fn</code> -- I am pretty sure of that. A language can reasonably decide to go either way here.</p>



<a name="247260607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247260607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247260607">(Jul 26 2021 at 20:55)</a>:</h4>
<p>I am not telling Rust to go one or the other side, I am just the lookout describing the design landscape. ;)</p>



<a name="247261064"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247261064" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247261064">(Jul 26 2021 at 20:59)</a>:</h4>
<p>are you suggesting that we should have some sort of holistic const story before moving forward on any of these fronts? I agree that at least laying out the potential design tradeoffs WRT all the different decisions would be nice, but I don't know who has that sort of broader perspective on const these days</p>



<a name="247264259"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247264259" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247264259">(Jul 26 2021 at 21:13)</a>:</h4>
<p>well I think we should have a rough idea of the lay of the land and not just look at the immediate next step, yes</p>



<a name="247264329"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247264329" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247264329">(Jul 26 2021 at 21:14)</a>:</h4>
<p>I'm trying to provide that perspective :D</p>



<a name="247268686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247268686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247268686">(Jul 26 2021 at 21:52)</a>:</h4>
<p>Do you have a document with your own vision for the future of const? I see the const-eval repo, but that seems to just show me things that have already been decided</p>



<a name="247299696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247299696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247299696">(Jul 27 2021 at 06:51)</a>:</h4>
<p>no not really, sorry. I'd also not say I have a "vision" -- by "perspective" I more mean that I (think I) have an idea for the possible choices we could make and their consequences. I dont necessarily have strong opinions for which choices we should make.</p>



<a name="247299713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247299713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247299713">(Jul 27 2021 at 06:52)</a>:</h4>
<p>whether or not <code>const fn</code> are runtime-deterministic is probably the biggest one here -- it touches on <code>const fn transmute</code>, const-fn-float, probably more</p>



<a name="247299776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247299776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247299776">(Jul 27 2021 at 06:52)</a>:</h4>
<p>(to make things more complicated, <em>if</em> ptr-to-int transmutes <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/286">truly are runtime UB</a>, then stabilizing <code>const_fn_transmute</code> does <em>not</em> allow one to write runtime-impure <code>const fn</code>... but allowing floats in <code>const fn</code> probably would... :/ )</p>



<a name="247300126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247300126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247300126">(Jul 27 2021 at 07:00)</a>:</h4>
<p>other discussions:</p>
<ul>
<li>structural equality / const generics -- I hope we can follow <a href="https://hackmd.io/Qvrj_eOFTkCHZrhJ7f1ItA">something like this sketch</a></li>
<li>traits calls, fn ptrs, <code>dyn Trait</code>... I think we need <code>const Trait</code> bounds and <code>const fn()</code> and <code>&amp;dyn const Trait</code> types (i.e. I dont think <span class="user-mention" data-user-id="124288">@oli</span> 's plan of making <code>Trait</code> bounds implicitly require <code>const</code> in const context will fly, since then trait bounds and types will be inconsistent).</li>
<li>heap allocations: honestly this one I am least sure about. the principled approach would be to treat allocation during CTFE as a different allocator, but that would be reflected in the type of everything so it might be horribly unergonomic...</li>
</ul>



<a name="247300636"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247300636" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247300636">(Jul 27 2021 at 07:07)</a>:</h4>
<p>You're essentially correct on the last point.</p>



<a name="247300721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247300721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247300721">(Jul 27 2021 at 07:09)</a>:</h4>
<ul>
<li>The compile time allocator <em>really is</em> a separate allocator from the runtime global allocator, and should be represented as such.</li>
<li>This means that we'd have a lot of ergonomics work to do because currently in rust having allocator-agnostic code is not really common.</li>
</ul>
<p>these are both true.</p>



<a name="247317775"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247317775" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247317775">(Jul 27 2021 at 10:51)</a>:</h4>
<p>So, my takeaway from all these discussions we've had previously was "we can either have unsafe code in const fn, or we can have runtime-determinism". Since in my personal opinion we 100% want the former, the latter becomes irrelevant. For const-prop/optimization purposes, we can always have the compiler infer purity, no need to have this be a guaranteed thing.</p>



<a name="247317919"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247317919" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247317919">(Jul 27 2021 at 10:53)</a>:</h4>
<p>well we could put the burden on unsafe code to uphold runtime-determinism</p>



<a name="247317952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247317952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247317952">(Jul 27 2021 at 10:54)</a>:</h4>
<p>but I am not sure how to do this in a principled way... like, making this precise requires some fancy binary logical relation machinery I think^^</p>



<a name="247319342"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319342" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319342">(Jul 27 2021 at 11:09)</a>:</h4>
<p>one option we might have is to still require that <em>sound</em> public <code>const fn</code> must be pure. that would be enough to let people write unsafe code that relies on <code>const fn</code> purity.</p>



<a name="247319489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319489">(Jul 27 2021 at 11:11)</a>:</h4>
<p>so instead of making it UB, we extend the notion of soundness:</p>
<ul>
<li>a public <code>fn</code> is sound if, when called with arbitrary arguments that satisfy the safety invariant, it runs without causing UB and if it returns something, the result satisfies the safety argument</li>
<li>moreover, a sound public <code>const fn</code> must be <em>pure</em>. &lt;insert definition of purity here&gt;</li>
</ul>



<a name="247319491"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319491" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319491">(Jul 27 2021 at 11:11)</a>:</h4>
<p>So... a <code>pub unsafe const fn</code> would not have to be pure?</p>



<a name="247319507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319507">(Jul 27 2021 at 11:11)</a>:</h4>
<p>correct</p>



<a name="247319516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319516">(Jul 27 2021 at 11:11)</a>:</h4>
<p>but it needs to document in its SAFETY comment the requirements that ensure purity</p>



<a name="247319588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319588">(Jul 27 2021 at 11:12)</a>:</h4>
<p>I am not saying that I am in favor of this proposal -- it probably falls down with floating-point operations, which are not pure due to non-determinism</p>



<a name="247319596"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319596" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319596">(Jul 27 2021 at 11:12)</a>:</h4>
<p>but I am saying that this would be a possible way forward</p>



<a name="247319745"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247319745" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247319745">(Jul 27 2021 at 11:14)</a>:</h4>
<p>The big question imo is whether there are actually <em>practical</em> examples that need purity for soundness that can't also just rely on optimizations to get the same performance without manually relying on the purity</p>



<a name="247327481"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247327481" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247327481">(Jul 27 2021 at 12:43)</a>:</h4>
<p>the "obvious" example for exploiting purity is memoization</p>



<a name="247330156"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247330156" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247330156">(Jul 27 2021 at 13:06)</a>:</h4>
<p>isn't memoization the wrong way around for this? If you get two different but indistinguishable return values for the same arguments, all that happens is that you are inefficient.</p>



<a name="247330408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247330408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247330408">(Jul 27 2021 at 13:09)</a>:</h4>
<p>if a function is impure, memoization changes behavior</p>



<a name="247330521"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247330521" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247330521">(Jul 27 2021 at 13:10)</a>:</h4>
<p>so if <code>memoize f</code> is supposed to be equivalent to <code>f</code> (the usual correctness condition)I, then <code>f</code> must be pure -- well, some effects are okay (non-determinism, for example), but most are not</p>



<a name="247330799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247330799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247330799">(Jul 27 2021 at 13:12)</a>:</h4>
<p>but hm since it can tolerate non-det then maybe it is indeed not a good example....</p>



<a name="247330840"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247330840" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247330840">(Jul 27 2021 at 13:12)</a>:</h4>
<p>things like <code>DerefMove</code>, dont they require side-effect-free deterministic functions?</p>



<a name="247345706"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247345706" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247345706">(Jul 27 2021 at 15:04)</a>:</h4>
<p>if a const allocator allocates 8 bytes twice in a row the two boxes returned are different. does that make the const allocator inherently impure?</p>



<a name="247346279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247346279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247346279">(Jul 27 2021 at 15:08)</a>:</h4>
<p>depends on how you declare purity <span aria-label="stuck out tongue" class="emoji emoji-1f61b" role="img" title="stuck out tongue">:stuck_out_tongue:</span> Like, without a definition of purity we can't really say anything here. From other discussions I got the impression that pure in haskell does not mean two arrays returned by an argumentless function have the same address, because the difference is not observable</p>



<a name="247346576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247346576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247346576">(Jul 27 2021 at 15:10)</a>:</h4>
<p>but here we can observe the difference, as writing to the one box will not write to the other box</p>



<a name="247346684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247346684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247346684">(Jul 27 2021 at 15:11)</a>:</h4>
<p>mutability is by itself rather problematic for pure functions afaict</p>



<a name="247390617"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247390617" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247390617">(Jul 27 2021 at 21:00)</a>:</h4>
<p>a pure <code>fn(&amp;mut T)</code> would be basically the same as a pure <code>fn(T) -&gt; T</code></p>



<a name="247390980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247390980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247390980">(Jul 27 2021 at 21:01)</a>:</h4>
<p>but yeah defining "pure" precisely is possible with some suitably heavy PL machinery ("logical relations"), but I think it's waaaay beyond the complexity budget we can expect people to spend on unsafe const code.</p>



<a name="247391141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/the%20guarantees%20of%20const/near/247391141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/the.20guarantees.20of.20const.html#247391141">(Jul 27 2021 at 21:02)</a>:</h4>
<p>to be fair, "soundness" is also a very complicated issue when you get deep into it, but lucky enough many people have very good intuition for it and that intuition typically does not lead astray</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>